﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace National.Dal
{
    public class BaseRepository<T, TS> where T : class where TS : DbContext, new()
    {
        //当前操作的数据库实例
        private DbContext db = DbContextFactory<TS>.GetCurrentDbContext();
        #region 添加
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Add(T entity)
        {

            db.Set<T>().Add(entity);
            return db.SaveChanges() > 0;

        }
        //添加多条数据
        public bool AddRange(List<T> entity)
        {

            db.Set<T>().AddRange(entity);
            return db.SaveChanges() > 0;

        }
        #endregion
        #region 删除
        /// <summary>
        /// 删除单条
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(T entity)
        {
            db.Entry(entity).State = EntityState.Deleted;
            return db.SaveChanges() > 0;
        }
        /// <summary>
        /// 删除多条
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public bool BatchDelete(List<T> entitys)
        {
            db.Set<T>().RemoveRange(entitys);

            return db.SaveChanges() > 0;
        }
        public virtual bool Delete(int id)
        {
            var entity = db.Set<T>().Find(id);//如果实体已经在内存中，那么就直接从内存拿，如果内存中跟踪实体没有，那么才查询数据库。
            if (entity != null) db.Set<T>().Remove(entity);
            return db.SaveChanges() > 0;
        }
        /// <summary>
        /// 根据ID删除多条
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool BatchDelete(params int[] ids)
        {
            foreach (var id in ids)
            {
                var entity = db.Set<T>().Find(id);
                if (entity != null)
                    db.Set<T>().Remove(entity);
            }
            return db.SaveChanges() > 0;
        }
        #endregion
        #region 修改
        //修改
        public bool Update(T entity)
        {
            db.Entry(entity).State = EntityState.Modified;
            return db.SaveChanges() > 0;
        }
        #endregion
        #region 查询
        /// <summary>
        /// 返回一个集合
        /// </summary>
        /// <param name="lambdaExpression"></param>
        /// <returns></returns>
        public List<T> QueryList(Expression<Func<T, bool>> lambdaExpression)
        {
            return db.Set<T>().Where(lambdaExpression).ToList();
        }
        /// <summary>
        /// 返回一个对象，一般根据主健不能查出两个,如果不存在返回默认值
        /// </summary>
        /// <param name="lambdaExpression"></param>
        /// <returns></returns>
        public T Query(Expression<Func<T, bool>> lambdaExpression)
        {
            return db.Set<T>().SingleOrDefault(lambdaExpression);
        }
        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="lambdaExpression"></param>
        /// <returns></returns>
        public bool Exists(Expression<Func<T, bool>> lambdaExpression)
        {
            return db.Set<T>().Any(lambdaExpression);
        }
        #endregion
        #region 分页
        /// <summary>
        /// 分页
        /// </summary>
        /// <typeparam name="S"></typeparam>
        /// <param name="PageSize"></param>
        /// <param name="PageIndex"></param>
        /// <param name="whereLambda"></param>
        /// <param name="orderbyLambda"></param>
        /// <param name="count"></param>
        /// <param name="isAsc"></param>
        /// <returns></returns>
        public List<T> QueryPageList<S>(int PageSize, int PageIndex, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, out int count, bool isAsc = true)

        {
            count = db.Set<T>().Where(whereLambda).Count();
            if (!isAsc)
            {
                return
                    db.Set<T>()
                    .Where(whereLambda).AsQueryable()
                    .OrderByDescending(orderbyLambda)
                    .Skip((PageIndex - 1) * PageSize)
                    .Take(PageSize)
                    .ToList();
            }
            else
            {
                return
                    db.Set<T>()
                    .Where(whereLambda).AsQueryable()
                    .OrderBy(orderbyLambda)
                    .Skip((PageIndex - 1) * PageSize)
                    .Take(PageSize)
                    .ToList();
            }
        }
        #endregion
    }
}
